
package control.servlet;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import model.math.Chance;
import bean.ActionBEAN;
import bean.CharacterBEAN;
import dao.ActionDAO;
import dao.CharacterDAO;
import dao.EquipmentDAO;
import dao.MailDAO;

/**
 * Servlet implementation class Navigation
 */
public class Navigation extends HttpServlet {
	private static final long	serialVersionUID	= 1L;
	private CharacterDAO		characterDAO;
	private ActionDAO			actionDAO;
	private MailDAO				mailDAO;
	private EquipmentDAO		equipmentDAO;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Navigation() {
		super();
	}

	public void init( ServletConfig config ) throws ServletException {
		characterDAO = (CharacterDAO) config.getServletContext().getAttribute(
				"CharacterDAO" );
		mailDAO = (MailDAO) config.getServletContext().getAttribute( "MailDAO" );
		actionDAO = (ActionDAO) config.getServletContext().getAttribute(
				"ActionDAO" );
		equipmentDAO = (EquipmentDAO) config.getServletContext().getAttribute(
				"EquipmentDAO" );
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet( HttpServletRequest request,
			HttpServletResponse response ) throws ServletException, IOException {
		String action = request.getParameter( "action" );
		HttpSession session = request.getSession();
		if( action == null ) {
			goTo( "index.jsp", request, response );
			return;
		}
		if( session.getAttribute( "ID" ) != null ) {
			int accountID = (Integer) session.getAttribute( "ID" );
			CharacterBEAN characterBEAN = characterDAO
					.getCharacterByID( accountID );
			changeLevel( characterBEAN );
			request.setAttribute( "character", characterBEAN );
			if( action.equals( "simpleCrime" ) ) {
				Chance chance = new Chance( characterBEAN );
				request.setAttribute( "chances", chance.simpleCrimeChances() );
				goToCrime( "WEB-INF/logged/crime/simpleCrime.jsp", request,
						response, characterBEAN, "simpleCrime" );
				return;
			} else if( action.equals( "bigCrime" ) ) {
				if( characterBEAN.getLevel() < 5 ) {
					goTo( "WEB-INF/logged/noPermission.jsp", request, response );
					return;
				}
				Chance chance = new Chance( characterBEAN );
				request.setAttribute( "chances", chance.bigCrimeChances() );
				goToCrime( "WEB-INF/logged/crime/bigCrime.jsp", request,
						response, characterBEAN, "bigCrime" );
				return;
			} else if( action.equals( "shootArea" ) ) {
				goToCrime( "WEB-INF/logged/crime/shootArea.jsp", request,
						response, characterBEAN, "shootArea" );
				return;
			} else if( action.equals( "mailBox" ) ) {
				request.setAttribute( "mailList", mailDAO
						.getMailsByID( characterBEAN.getCharacterID() ) );
				goTo( "WEB-INF/logged/mailBox.jsp", request, response );
				return;
			} else if( action.equals( "murder" ) ) {
				request.setAttribute( "weaponList", mailDAO
						.getMailsByID( characterBEAN.getCharacterID() ) );
				request.setAttribute( "equipmentBEAN", equipmentDAO
						.getEquipmentByID( accountID ) );
				goTo( "WEB-INF/logged/crime/murder.jsp", request, response );
				return;
			} else if( action.equals( "bank" ) ) {
				goTo( "WEB-INF/logged/bank.jsp", request, response );
				return;
			} else if( action.equals( "shop" ) ) {
				goTo( "WEB-INF/logged/shop/shopOverview.jsp", request, response );
				return;
			} else if( action.equals( "support" ) ) {
				goTo( "WEB-INF/logged/support.jsp", request, response );
				return;
			} else if( action.equals( "faq" ) ) {
				goTo( "WEB-INF/logged/faq.jsp", request, response );
				return;
			} else if( action.equals( "adminControl" )
					&& characterBEAN.isAdministrator() ) {
				goTo( "WEB-INF/logged/admin/managementOverview.jsp", request,
						response );
				return;
			} else {
			}
		} else if( action.equals( "index" ) ) {
			goTo( "index.jsp", request, response );
			return;
		} else if( action.equals( "statisticsOff" ) ) {
			goTo( "WEB-INF/loggedOff/statistics.jsp", request, response );
			return;
		} else if( action.equals( "sponsor" ) ) {
			goTo( "WEB-INF/sponsors.jsp", request, response );
			return;
		} else if( action.equals( "contact" ) ) {
			goTo( "WEB-INF/contact.jsp", request, response );
			return;
		} else if( action.equals( "register" ) ) {
			goTo( "WEB-INF/register.jsp", request, response );
			return;
		} else {
			goTo( "WEB-INF/404NotFound.jsp", request, response );
		}
	}

	private void goToCrime( String url, HttpServletRequest request,
			HttpServletResponse response, CharacterBEAN characterBEAN,
			String action ) throws ServletException, IOException {
		ActionBEAN a = actionDAO
				.getActionsByID( characterBEAN.getCharacterID() );
		if( actionIsLocked( a.getJail() ) ) {
			request.setAttribute( "timeLeft", getTimeLeft( a.getJail() ) );
			goTo( "WEB-INF/logged/crime/jailWaitTime.jsp", request, response );
			return;
		} else if( action.equals( "simpleCrime" ) ) {
			System.out.println( "simpleCrimeCheck" );
			if( actionIsLocked( a.getSimpleCrime() ) ) {
				request.setAttribute( "timeLeft", getTimeLeft( a
						.getSimpleCrime() ) );
				goTo( "WEB-INF/logged/crime/crimeWaitTime.jsp", request,
						response );
				return;
			} else {
				goTo( url, request, response );
				return;
			}
		} else if( action.equals( "bigCrime" ) ) {
			if( actionIsLocked( a.getBigCrime() ) ) {
				request.setAttribute( "timeLeft", getTimeLeft( a.getBigCrime() ) );
				goTo( "WEB-INF/logged/crime/crimeWaitTime.jsp", request,
						response );
				return;
			} else {
				goTo( url, request, response );
				return;
			}
		} else if( action.equals( "shootArea" ) ) {
			if( actionIsLocked( a.getShootArea() ) ) {
				request.setAttribute( "timeLeft",
						getTimeLeft( a.getShootArea() ) );
				goTo( "WEB-INF/logged/crime/crimeWaitTime.jsp", request,
						response );
				return;
			} else {
				goTo( url, request, response );
				return;
			}
		} else {
			goTo( url, request, response );
		}
	}

	private String getTimeLeft( String jail ) {
		return calculateTimeLeft( getCalendarFromString( jail ) );
	}

	public String calculateTimeLeft( Calendar endTime ) {
		long millisInADay = 24 * 3600 * 1000;
		Calendar calendar = new GregorianCalendar();
		long msDiff = endTime.getTimeInMillis() - calendar.getTimeInMillis();
		if( msDiff > 0 ) {
			int year = (int) ( msDiff / ( millisInADay * 365 ) );
			msDiff = msDiff - ( year * millisInADay * 365 );
			int day = (int) ( msDiff / millisInADay );
			msDiff = msDiff - ( day * millisInADay );
			int hour = (int) ( msDiff / ( 3600 * 1000 ) );
			msDiff = msDiff - ( hour * ( 3600 * 1000 ) );
			int min = (int) ( msDiff / ( 1000 * 60 ) );
			msDiff = msDiff - ( min * ( 1000 * 60 ) );
			int sec = (int) ( msDiff / 1000 );
			return makeNiceTimeLeft( year, day, hour, min, sec );
		} else {
			return "0 seconds";
		}
	}

	public String makeNiceTimeLeft( int year, int day, int hour, int min,
			int sec ) {
		String timeLeft = "";
		timeLeft = hour + " hour(s) ";
		timeLeft = timeLeft + min + " min(s) ";
		timeLeft = timeLeft + sec + " sec(s) ";
		return timeLeft;
	}

	private boolean actionIsLocked( String jail ) {
		if( getCalendarFromString( jail ).getTimeInMillis() > getCurrentTime()
				.getTimeInMillis() ) {
			return true;
		} else {
			return false;
		}
	}

	private Calendar getCurrentTime() {
		Calendar cal = new GregorianCalendar();
		return cal;
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost( HttpServletRequest request,
			HttpServletResponse response ) throws ServletException, IOException {
	}

	private void goTo( String action, HttpServletRequest request,
			HttpServletResponse response ) throws ServletException, IOException {
		try {
			RequestDispatcher dispatcher = request
					.getRequestDispatcher( action );
			dispatcher.forward( request, response );
		} catch( Exception e ) {
			e.printStackTrace();
		}
	}

	public String getStringFromCalendar( Calendar time ) {
		if( time == null )
			return "";
		SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
		return sdf.format( time.getTime() );
	}

	/**
	 * 
	 * @param time
	 *            format = yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public Calendar getCalendarFromString( String time ) {
		if( time == null )
			return null;
		SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
		Date date = null;
		try {
			date = (Date) sdf.parse( time );
		} catch( ParseException e ) {
			e.printStackTrace();
			return new GregorianCalendar();
		}
		Calendar cal = new GregorianCalendar();
		cal.setTime( date );
		return cal;
	}

	public void changeLevel( CharacterBEAN character ) {
		if( character.getExperienceToGoInPercentage( character.getExperience(),
				character.getLevel() ) > 100 ) {
			characterDAO.changeLevel( character.getLevel() + 1, character
					.getCharacterID() );
		}
	}
}
